/**
	**********************************************************************
	**********************************************************************
	**********************************************************************
	*	文件名： 	onenet.c
	*	作者： 		zh
	*	日期： 		
	*	版本： 		V1.1
	*	说明： 		与onenet平台的数据交互接口层
	*	修改记录：	
	*	
	**********************************************************************
	**********************************************************************
	**********************************************************************
**/

//单片机头文件
#include "stm32f10x.h"

//网络设备
#include "esp8266.h"

//协议文件
#include "onenet.h"
#include "mqttkit.h"
#include "cJSON.h"

//硬件驱动
#include "usart.h"
#include "Xdelay.h"
#include "LED.h"
#include "PWM.h"
//#include "dht11.h"
#include "usart_Debug.h"
//C库
#include <string.h>
#include <stdio.h>

#define PROID		"a8Ifqm939M"  //产品ID

#define AUTH_INFO	"version=2018-10-31&res=products%2Fa8Ifqm939M%2Fdevices%2Fdevice&et=1756953821&method=md5&sign=BLEVzs%2Bk0ksCvkyE%2FoCx2Q%3D%3D"  //鉴权信息

#define DEVID		"device"   //设备名称

extern unsigned char esp8266_buf[128];
extern uint8_t humility,humilityfloat,temperature,temperaturefloat;
//==========================================================
//	函数名称：	OneNet_DevLink
//
//	函数功能：	与onenet创建连接
//
//	入口参数：	无
//
//	返回参数：	1-成功	0-失败
//
//	说明：		与onenet平台建立连接
//==========================================================
_Bool OneNet_DevLink(void)
{
	
	MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};					//协议包

	unsigned char *dataPtr;
	
	_Bool status = 1;
	
	if(MQTT_PacketConnect(PROID, AUTH_INFO, DEVID, 256, 1, MQTT_QOS_LEVEL0, NULL, NULL, 0, &mqttPacket) == 0)  //修改clean_session=1
	{
		
		ESP8266_SendData(mqttPacket._data, mqttPacket._len);	//上传平台
		
		dataPtr = ESP8266_GetIPD(250);	//等待平台响应
		if(dataPtr != NULL)
		{
			if(MQTT_UnPacketRecv(dataPtr) == MQTT_PKT_CONNACK)
			{
				switch(MQTT_UnPacketConnectAck(dataPtr))
				{
					case 0:printf( "Tips:	连接成功\r\n");status = 0;break;
					
					case 1:printf( "WARN:	连接失败：协议错误\r\n");break;
					case 2:printf( "WARN:	连接失败：非法的clientid\r\n");break;
					case 3:printf( "WARN:	连接失败：服务器失败\r\n");break;
					case 4:printf( "WARN:	连接失败：用户名或密码错误\r\n");break;
					case 5:printf("WARN:	连接失败：非法链接(比如token非法)\r\n");break;
					
					default:printf( "ERR:	连接失败：未知错误\r\n");break;
				}
			}
		}
		
		MQTT_DeleteBuffer(&mqttPacket);		//删包
	}
	
	return status;
	
}
extern bool door_status;

//访问ONENET需要提交JSON数据，就获取到的温湿度转换为JSON数据形式
//unsigned char MqttOnenet_Savedata(char *t_payload)
//{
//	
//	char json[]="{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"temp\":{\"value\":%lf}}}";  //更换了JSON数据形式，符合OneNET需求
//   char t_json[200];
//    unsigned short json_len;
//	sprintf(t_json, json, temperature);
//    json_len = strlen(t_json)/sizeof(char);
//  	memcpy(t_payload, t_json, json_len);
//	
//    return json_len;	
//}
extern uint8_t humility,humilityfloat,temperature,temperaturefloat;
extern uint16_t adcvalue;
unsigned char OneNet_FillBuf(char *buf)
{
	
	char text[100];
	
	memset(text, 0, sizeof(text));
	
	strcpy(buf, "{\"id\":\"123\",\"params\":{");
	
	memset(text, 0, sizeof(text));
	sprintf(text, "\"temp\":{\"value\":%d},", temperature+temperaturefloat/10);
	strcat(buf, text);
	
	memset(text, 0, sizeof(text));
	sprintf(text, "\"humility\":{\"value\":%d},", humility+humilityfloat/10);
	strcat(buf, text);

	memset(text, 0, sizeof(text));
	sprintf(text, "\"sun\":{\"value\":%d},",adcvalue);
	strcat(buf, text);
	
	memset(text, 0, sizeof(text));
	sprintf(text, "\"led\":{\"value\":%s},", LED_status ? "true" : "false");
	strcat(buf, text);
	

	
	memset(text, 0, sizeof(text));
	sprintf(text, "\"door\":{\"value\":%s}", door_status ? "true" : "false");
	strcat(buf, text);
	//printf("%lf,%lf\r\n",temperature*1.0+temperaturefloat%10, humility*1.0+humilityfloat/10);

	
	strcat(buf, "}}");
	
	return strlen(buf);

}
//==========================================================
//	函数名称：	OneNet_SendData
//
//	函数功能：	上传数据到平台
//
//	入口参数：	type：发送数据的格式
//
//	返回参数：	无
//
//	说明：		
//==========================================================
void OneNet_SendData(void)
{
	
	MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};		//协议包
	
	char buf[256];
	short body_len = 0, i = 0;
	memset(buf, 0, sizeof(buf));    //清空buff
	body_len=OneNet_FillBuf(buf);	
	
	if(body_len)
	{
		
		if(MQTT_PacketSaveData(DEVID, body_len, NULL, 5, &mqttPacket) == 0)							//封包
		{
			
			for(; i < body_len; i++)
				mqttPacket._data[mqttPacket._len++] = buf[i];
			
			ESP8266_SendData(mqttPacket._data, mqttPacket._len);									//上传数据到平台
			
			MQTT_DeleteBuffer(&mqttPacket);	
	//printf("OneNet_SendData succeed\r\n");			//删包
		}
		else 
			printf("OneNet_SendData error\r\n");
	}
	
}
//==========================================================
//	函数名称：	OneNET_Subscribe
//
//	函数功能：	订阅
//
//	入口参数：	无
//
//	返回参数：	无
//
//	说明：		
//==========================================================
void OneNET_Subscribe(void)
{
	
	MQTT_PACKET_STRUCTURE mqtt_packet = {NULL, 0, 0, 0};						//协议包
	
	char topic_buf[56];
	const char *topic = topic_buf;

	snprintf(topic_buf, sizeof(topic_buf), "$sys/%s/%s/thing/property/set", PROID, DEVID);
	
	printf("Subscribe Topic: %s\r\n", topic_buf);
	
	if(MQTT_PacketSubscribe(MQTT_SUBSCRIBE_ID, MQTT_QOS_LEVEL0, &topic, 1, &mqtt_packet) == 0)
	{
		ESP8266_SendData(mqtt_packet._data, mqtt_packet._len);					//向平台发送订阅请求
	//	printf("12345678910\r\n");
		MQTT_DeleteBuffer(&mqtt_packet);										//删包
	}

}
//==========================================================
//	函数名称：	OneNet_RevPro
//
//	函数功能：	平台返回数据检测
//
//	入口参数：	dataPtr：平台返回的数据
//
//	返回参数：	无
//
//	说明：		
//==========================================================

void OneNet_RevPro(unsigned char *cmd)
{
	
	char *req_payload = NULL;
	char *cmdid_topic = NULL;
	
	unsigned short topic_len = 0;
	unsigned short req_len = 0;
	
	unsigned char qos = 0;
	static unsigned short pkt_id = 0;
	
	unsigned char type = 0;
	
	short result = 0;
	
	//原始数据 -> cjson数据
	cJSON *raw_jason;
	// cjson中摘出标识符变量
	cJSON *params_jason;

	//这里定义 cjson格式的变量名,例如 *led_jason
	cJSON *led_jason,*door_jason;
	
	type = MQTT_UnPacketRecv(cmd);
	//UsartPrintf(USART_DEBUG, "688\r\n");
	switch(type)
	{
		case MQTT_PKT_PUBLISH:																//接收的Publish消息
//			UsartPrintf(USART_DEBUG, "689\r\n");
			result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);
			
			if(result == 0)
			{

				
				printf("topic: %s, topic_len: %d, payload: %s, payload_len: %d\r\n",
																	cmdid_topic, topic_len, req_payload, req_len);
				
				//将原始字符串信息,转化成cjson格式
				raw_jason = cJSON_Parse(req_payload);//解析原始字符串数据到raw_jason
				//从raw_jason中提取params字符段到params_jason
				params_jason = cJSON_GetObjectItem(raw_jason,"params");
				//然后再从params_jason中提取要操作的器件,

				
				
				door_jason = cJSON_GetObjectItem(params_jason,"door");
				led_jason = cJSON_GetObjectItem(params_jason,"led");
				//判断对应cjson 标识符变量 是否为空, 不空,则代表有对应的下发信息
				if(door_jason != NULL)
				{
					//printf("door\r\n");
					if(door_jason->type == cJSON_True) 
					{
						Servo_SetAngle(180);
						door_status=1;
					}
					else
					{
						Servo_SetAngle(0);
						door_status=0;
					}
				}
				
				delay_ms(50);
				if(led_jason != NULL)
				{
					//printf("LED\r\n");
					if(led_jason->type == cJSON_True) 
					{
						LED_ON();
					}
					else
					{
						LED_OFF();
					}
				}


				cJSON_Delete(raw_jason);
			}
			
		case MQTT_PKT_PUBACK:														//发送Publish消息，平台回复的Ack
//			UsartPrintf(USART_DEBUG, "111\r\n");
			if(MQTT_UnPacketPublishAck(cmd) == 0)
//				UsartPrintf(USART_DEBUG, "Tips:	MQTT Publish Send OK\r\n");
			
		break;
		
		case MQTT_PKT_SUBACK:																//发送Subscribe消息的Ack
//			UsartPrintf(USART_DEBUG, "222\r\n");
			if(MQTT_UnPacketSubscribe(cmd) == 0)
				printf("Tips:	MQTT Subscribe OK\r\n");
			else
				printf("Tips:	MQTT Subscribe Err\r\n");
		
		break;
		
		default:
//			UsartPrintf(USART_DEBUG, "333\r\n");
			result = -1;
		break;
	}
	
	ESP8266_Clear();									//清空缓存
	
	if(result == -1)
		return;
	

	
	if(type == MQTT_PKT_CMD || type == MQTT_PKT_PUBLISH)
	{
		MQTT_FreeBuffer(cmdid_topic);
		MQTT_FreeBuffer(req_payload);
	}

}

